package com.ilearn.iodata.iolingo.controller;

import com.ilearn.iodata.iolingo.service.GetCollectionService;
import com.ilearn.iodata.iolingo.service.processor.core.api.GenericODataGetHandler;
import com.ilearn.iodata.iolingo.service.provider.GenericEdmProvider;
import org.apache.olingo.commons.api.edm.EdmException;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import java.nio.charset.Charset;
import java.util.concurrent.Callable;

import static com.ilearn.iodata.iolingo.constant.OdataConst.NAMESPACE;
import static com.ilearn.iodata.iolingo.utils.UrlInit.createODataRequest;

/**
 * http://localhost:8080/odata?$appId=1917&$apiName=ahhja&$apiVersion=1.0&$orderby=1,2,3&$top=1000&$select=DEAL_DATE,PHONE_NO,SHOULD_PAY&$filter=DEAL_DATE%20eq%20201801%20and%20PHONE_NO%20contains%20(%27139%27)
 */
@RestController
@RequestMapping("/chinabond.svc")
public class OdataController {

    /*@Autowired
    private EntityCollectionProcessor enityCollectionProcessor;

    @Autowired
    private EntityProcessor entityProcessor;

    @Autowired
    private GenericPrimitiveProcessor genericPrimitiveProcessor;
*/
    @Autowired
    GetCollectionService getCollectionService;


    @Autowired
    GenericEdmProvider genericEdmProvider;

    @Autowired
    DataSource dataSource;


    /**
     * The split.
     */
    private int split = 0;

    @RequestMapping(value = {"","*/**"})
    public Callable<ResponseEntity<String>> callable(HttpServletRequest req) {
        // 这么做的好处避免web server的连接池被长期占用而引起性能问题，
        // 调用后生成一个非web的服务线程来处理，增加web服务器的吞吐量。
        return new Callable<ResponseEntity<String>>() {
            @Override
            public ResponseEntity<String> call() throws Exception {
                //Thread.sleep(3 * 1000L);
                return process(req);
                //return "小单 - " + System.currentTimeMillis() + " IP:" + req.getRemoteAddr();
            }
        };
    }

    /**
     * Process.
     *
     * @param req the req
     * @return the response entity
     */
    public ResponseEntity<String> process(HttpServletRequest req) {

        //System.out.println("ReqUrl:" + req.getRequestURL().toString());



            try {
            /*ODataRequest oDataRequest = createODataRequest(req, split);

            OData odata = OData.newInstance();*/
            /*ServiceMetadata edm = odata.createServiceMetadata(genericEdmProvider,
                    new ArrayList<EdmxReference>());*/

                GenericODataGetHandler genericODataGetHandler = new GenericODataGetHandler(NAMESPACE, dataSource, getCollectionService, genericEdmProvider);


                ODataResponse oDataResponse = genericODataGetHandler.process(req);

            /*ODataHttpHandler handler = odata.createHandler(edm);
            handler.register(enityCollectionProcessor);
            handler.register(entityProcessor);
            handler.register(genericPrimitiveProcessor);

            String oDataReqStr = JSON.toJSONString(oDataRequest);

            System.out.println("oDataReqStr:" + oDataReqStr);

            ODataResponse oDataResponse = handler.process(oDataRequest);
            */
                String responseStr = StreamUtils.copyToString(
                        oDataResponse.getContent(), Charset.defaultCharset());
                MultiValueMap<String, String> headers = new HttpHeaders();

                for (String key : oDataResponse.getAllHeaders().keySet()) {
                    //System.out.println("responseHeader: key:" + key + " value:" + oDataResponse.getAllHeaders().get(key).toString());
                    String primValue = oDataResponse.getAllHeaders().get(key).toString();
                    String value = primValue.substring(1, primValue.length() - 1);
                    //System.out.println("value:" + value);
                    headers.add(key, value);
                }
                return new ResponseEntity<String>(responseStr, headers,
                        HttpStatus.valueOf(oDataResponse.getStatusCode()));


            } catch (Exception ex) {
            throw new EdmException("未知错误");
        }

    }
}
